package vn.cuhanh.models;

import java.util.Calendar;

import org.json.JSONException;
import org.json.JSONObject;

import vn.cuhanh.MainActivity;
import vn.cuhanh.R;
import vn.cuhanh.bean.CharInfo;
import vn.cuhanh.fragment.CharacterInfoFragment;
import vn.cuhanh.sys.DBAdapter;
import vn.cuhanh.utils.HelperFunc;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;

public class Model_CharInfo {

	public static String getLevelInfoFromScore(Context ctx, int score) {
		DBAdapter dbAdapter;
		Cursor cursor = null;
		dbAdapter = new DBAdapter(ctx, ctx.getResources().getString(
				R.string.levelTable));
		try {
			if (dbAdapter.isClosed()) {
				dbAdapter.open();
			}
			cursor = dbAdapter.fetch("minScore <= '" + String.valueOf(score) + "' AND (maxScore = 0 OR maxScore > " + String.valueOf(score) + ")");
			return getLevelInfoFromScore(cursor, score);
		} catch (SQLException e) {
			HelperFunc.readStackTrace(e);
		} finally {
			try {
				if (cursor != null) {
					cursor.close();
				}
				dbAdapter.close();
			} catch (Exception e) {
				HelperFunc.readStackTrace(e);
			}
		}
		return null;
	}

	private static String getLevelInfoFromScore(Cursor cursor, int score) {
		cursor.moveToFirst();
		if (cursor.getCount() < 1 || cursor.isAfterLast()) {
			HelperFunc.readStackTrace(new Exception("Can not find level associated score: " + score));
			return "";
		}
		
		return String.valueOf(cursor.getInt(cursor.getColumnIndexOrThrow("id"))) 
				+ " " + cursor.getString(cursor.getColumnIndexOrThrow("name"));
	}

	public static CharInfo getCharInfo(Context ctx, String userName) {
		DBAdapter dbAdapter;
		Cursor cursor = null;
		dbAdapter = new DBAdapter(ctx, ctx.getResources().getString(
				R.string.charInfoTable));
		try {
			if (dbAdapter.isClosed()) {
				dbAdapter.open();
			}
			cursor = dbAdapter.fetch("username = '" + userName + "'");

			if (cursor.getCount() > 0) {
				return getCharInfoFromDatabase(cursor);
			}
		} catch (SQLException e) {
			HelperFunc.readStackTrace(e);
		} finally {
			try {
				if (cursor != null) {
					cursor.close();
				}
				dbAdapter.close();
			} catch (Exception e) {
				HelperFunc.readStackTrace(e);
			}
		}
		return null;
	}
	
	public static void addCharInfoToDatabase(Context ctx, CharInfo charInfo, String userName) {
		ContentValues values = new ContentValues();
		values.put("username", userName);
		values.put("userId", charInfo.getId());
		values.put("name", charInfo.getName());
		values.put("score", charInfo.getScore());
		values.put("sex", charInfo.getSex());
		values.put("mate_name", charInfo.getMate_name());
		values.put("charm", charInfo.getCharm());
		values.put("flower", charInfo.getFlower());
		values.put("eggs", charInfo.getEggs());
		values.put("online_time", charInfo.getOnline_time());
		values.put("m3g_money", charInfo.getM3g_money());
		values.put("food", charInfo.getFood());
		values.put("soldiers", charInfo.getSoldier());
		values.put("lastUpdate", (long)(Calendar.getInstance().getTimeInMillis() / 1000));
		DBAdapter dbAdapter = new DBAdapter(ctx, ctx.getResources().getString(R.string.charInfoTable));
		
		try {
			if (dbAdapter.isClosed())
				dbAdapter.open();
			if(dbAdapter.insert(values) == -1) {
				dbAdapter.update(values, "username = '" + userName + "'");
			}
		} catch (SQLException e) {
			HelperFunc.readStackTrace(e);
		} catch (IllegalArgumentException e) {
			HelperFunc.readStackTrace(e);
		} finally {
		}
		try {
			dbAdapter.close();
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
		}
	}

	public static CharInfo getCharInfoFromDatabase(Cursor cursor) {
		cursor.moveToFirst();
		CharInfo charInfo = null;
		if(cursor.isAfterLast()) {
			return charInfo;
		}
		charInfo = new CharInfo(
				cursor.getLong(cursor.getColumnIndexOrThrow("userId")),
				cursor.getString(cursor.getColumnIndexOrThrow("name")),
				cursor.getLong(cursor.getColumnIndexOrThrow("score")),
				cursor.getString(cursor.getColumnIndexOrThrow("sex")),
				cursor.getString(cursor.getColumnIndexOrThrow("mate_name")),
				cursor.getLong(cursor.getColumnIndexOrThrow("charm")),
				cursor.getLong(cursor.getColumnIndexOrThrow("flower")),
				cursor.getLong(cursor.getColumnIndexOrThrow("eggs")),
				cursor.getLong(cursor.getColumnIndexOrThrow("online_time")),
				cursor.getLong(cursor.getColumnIndexOrThrow("m3g_money")),
				cursor.getLong(cursor.getColumnIndexOrThrow("food")),
				cursor.getLong(cursor.getColumnIndexOrThrow("soldiers"))
				);
		charInfo.setLastUpdate(cursor.getLong(cursor.getColumnIndexOrThrow("lastUpdate")));
		return charInfo;
	}
	
	/**
	 * 
	 * @param ctx
	 * @param jsonString
	 * @return 1: success
	 *         2: no network, use local info
	 *         0: unknown error
	 *         -1: no net work
	 *         -2: no char found
	 */
	public static int handleCharInfoJson(Context ctx, String jsonString) {
		if(jsonString == null || jsonString.isEmpty()) {
			if(CharacterInfoFragment.charInfo != null) { //local saved charInfo exist, it may be expired.
				return 2;
			}
			return -1;
		}
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			int result = jsonObject.getInt("result");
			if(result == 0) {
				return -2;
			}
			JSONObject data = jsonObject.getJSONObject("data");
			CharInfo charInfo = new CharInfo(
					(long)MainActivity.userId,
					data.getString("name"),
					data.getLong("score"),
					data.getString("sex"),
					data.getString("mate_name"),
					data.getLong("charm"),
					data.getLong("flower"),
					data.getLong("eggs"),
					data.getLong("online_time"),
					data.getLong("m3g_money"),
					data.getLong("food"),
					data.getLong("soldiers")
					);
			//insert or update to SQLite
			addCharInfoToDatabase(ctx, charInfo, MainActivity.username);
			CharacterInfoFragment.charInfo = charInfo;
			return 1;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			HelperFunc.readStackTrace(e);
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
		}
		return 0;
	}
	
	/**
	 * 
	 * @param ctx
	 * @param jsonString
	 * @return 1: success
	 *         2: no network, use local info
	 *         0: unknown error
	 *         -1: no net work
	 *         -2: no char found
	 */
	public static int loadCharInfoFromInternet(Context ctx) {
		// TODO Auto-generated method stub
		final String response = HelperFunc.getDataFromSv(ctx.getResources().getString(R.string.getCharInfoUrl) + String.valueOf(MainActivity.userId));
		return handleCharInfoJson(ctx, response);
	}
}
